import Clipboard from "clipboard";

export interface MYel extends HTMLElement {
  __copyText__: (e: MouseEvent) => void;
}

export class ClipboardUtils {
  static copyText(el: MYel, text: string, e: MouseEvent) {
    return new Promise<void>((resolve, reject) => {
      const cli = new Clipboard(el, {
        text: () => text
      })
      cli.on("success", () => {
        cli.destroy()
        resolve()
      })
      cli.on('error', () => {
        cli.destroy()
        reject()
      })
      // @ts-ignore
      cli.onClick(e) // 解决第一次点击复制没用的问题
    })
  }

  static copyToClipboard(text: string) {
    return new Promise<string>((resolve, reject) => {
      const el = document.createElement('div') as unknown as MYel;
      document.body.appendChild(el)
      el.__copyText__ = (e: MouseEvent) => {
        if (ClipboardUtils.isSupported()) {
          ClipboardUtils.copyText(el, text, e).then(() => {
            resolve('已复制到剪切板')
          }).catch(() => {
            reject('复制失败')
          })
        } else {
          reject('当前浏览器不支持复制功能')
        }
        document.body.removeChild(el)
      }
      el.addEventListener('click', el.__copyText__)
      el.click()
    })
  }

  static isSupported = Clipboard.isSupported

  static async getClipboardText() {
    let textHtml: string = '', textPlain: string = '';
    if (window.navigator?.clipboard) {
      let clipboardItems
      try {
        clipboardItems = await window.navigator.clipboard.read();
      } catch (e) {
        // @ts-ignore
        const result = await navigator.permissions.query({name: 'clipboard-read'})
        const hasFocus = document.hasFocus()//这个是重点，可判断是否为当前dom页面
        if (hasFocus && (result.state === 'granted' || result.state === 'prompt')) {
          clipboardItems = navigator.clipboard.readText()
        }
      }
      for (const clipboardItem of clipboardItems) {
        for (const type of clipboardItem.types) {
          const item = await clipboardItem.getType(type);
          if (item && item.type == 'text/html') {
            textHtml = await item.text();
          }
          if (item && item.type == 'text/plain') {
            textPlain = await item.text();
          }
        }
      }
    } else {
      // @ts-ignore
      if (window.AllowClipboard) { // https://github.com/itsmikeeng/AllowClipboard
        // @ts-ignore
        const clipboardClient = new AllowClipboard.Client.ClipboardClient();
        const readData = (): Promise<string> => {
          return new Promise((resolve, reject) => {
            clipboardClient.read(function (success: boolean, data: string) {
              if (success) {
                resolve(data)
              } else {
                reject(data)
              }
            });
          })
        }
        textPlain = await readData()
      } else {
        alert('请安装浏览器插件AllowClipboard')
        throw {textHtml, textPlain}
      }
    }
    return {textHtml, textPlain}
  }
}
